home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume3 / getline < prev    next >
Encoding:
Text File  |  1989-02-03  |  6.2 KB  |  222 lines

  1. Path: xanth!mcnc!gatech!bloom-beacon!tut.cis.ohio-state.edu!husc6!necntc!ncoast!allbery
  2. From: daveb@geac.UUCP (David Collier-Brown)
  3. Newsgroups: comp.sources.misc
  4. Subject: v03i018: getline -- get a long line
  5. Summary: an fgets with an expanding cache
  6. Keywords: fgets getline cache
  7. Message-ID: <2751@geac.UUCP>
  8. Date: 16 May 88 15:23:12 GMT
  9. Sender: allbery@ncoast.UUCP
  10. Reply-To: daveb@geac.UUCP (David Collier-Brown)
  11. Organization: Geac
  12. Lines: 207
  13. Approved: allbery@ncoast.UUCP
  14.  
  15. comp.sources.misc: Volume 3, Issue 18
  16. Submitted-By: "David Collier-Brown" <daveb@geac.UUCP>
  17. Archive-Name: getline
  18.  
  19.  The following is a function to get a long (possibly arbitrarily
  20. long) line from a stream.  I've written it twice, so I guess it may
  21. be useful to others.
  22.   Tested ONLY on a Vax-Ultrix machine, so beware of machine
  23. dependencies that got by my jaundiced eye.
  24.  
  25. #! /bin/sh
  26. # This is a shell archive.  Remove anything before this line, then unpack
  27. # it by saving it into a file and typing "sh file".  To overwrite existing
  28. # files, type "sh file -c".  You can also feed this as standard input via
  29. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  30. # will see the following message at the end:
  31. #        "End of shell archive."
  32. # Contents:  getline.c Makefile getline.1
  33. # Wrapped by daveb@geac on Mon May 16 11:00:49 1988
  34. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  35. if test -f getline.c -a "${1}" != "-c" ; then 
  36.   echo shar: Will not over-write existing file \"getline.c\"
  37. else
  38. echo shar: Extracting \"getline.c\" \(1777 characters\)
  39. sed "s/^X//" >getline.c <<'END_OF_getline.c'
  40. X/*
  41. X * getline.c -- get a line into a variable-size cache. Otherwise the
  42. X *    behavior is identical to fgets.
  43. X */
  44. X#include <stdio.h>
  45. X
  46. X#define BADEXIT 3    /* Nonzero is sufficent. 3 implies badness. */
  47. X#define INITIAL_CHUNK 60  /* Purely a heuristic value. */
  48. X#define CHUNKSIZE 10
  49. X
  50. X/* 
  51. X * getline -- actually get the line. Behaves as expected on an eof
  52. X *    at the beginning of a line or at end of file.  Dependant on
  53. X *    the behavior of fgets as to what happens when an EOF is entered 
  54. X *    from a terminal in the middle of a line.  Under Ultrix/Berkley
  55. X *    TTY handling, the ^D seems to disappear... 
  56. X */ 
  57. X char *
  58. Xgetline(fp) FILE *fp; {
  59. X    extern char *realloc(), *malloc();
  60. X    extern char *lastCharacter();
  61. X    extern void exit();
  62. X    static char *cache = NULL;
  63. X    static int cacheSize = 0;
  64. X
  65. X    if (cache == NULL) {
  66. X        /* Its the first time... */
  67. X        if ((cache= malloc(INITIAL_CHUNK)) == NULL) {
  68. X            (void) fprintf(stderr,"getline ran out of space (can't happen)\n");
  69. X            exit(BADEXIT);
  70. X        }
  71. X        cacheSize = INITIAL_CHUNK;
  72. X    }
  73. X
  74. X    /* For all cases... */
  75. X    if (fgets(cache,cacheSize,fp) == NULL) {
  76. X        /* We hit an eof in the last line. */
  77. X        return NULL;
  78. X    }
  79. X    while (*lastCharacter(cache) != '\n') {
  80. X        /* We have to read some more... */
  81. X        if ((cache= realloc(cache,(unsigned)cacheSize+CHUNKSIZE)) == NULL) {
  82. X            (void) fprintf(stderr,"getline ran out of space: line longer than available memory\n");
  83. X            exit(BADEXIT);
  84. X        }
  85. X        if (fgets(&cache[cacheSize-1],CHUNKSIZE+1,fp) == NULL) {
  86. X            cacheSize += CHUNKSIZE;
  87. X            return cache;
  88. X        }
  89. X        else {
  90. X            cacheSize += CHUNKSIZE;
  91. X        }
  92. X    }
  93. X    /* We've got a line ending in \n... */
  94. X    return cache;
  95. X}
  96. X
  97. X
  98. X static char *
  99. XlastCharacter(p) char *p; {
  100. X    while (p[1] != '\0')
  101. X        p++;
  102. X    return p;
  103. X }
  104. X
  105. X#ifdef TEST
  106. Xmain() {
  107. X    char    *p;
  108. X
  109. X    while ((p=getline(stdin)) != NULL)
  110. X        fputs(p,stdout);
  111. X}
  112. X#endif
  113. X
  114. END_OF_getline.c
  115. if test 1777 -ne `wc -c <getline.c`; then
  116.     echo shar: \"getline.c\" unpacked with wrong size!
  117. fi
  118. # end of overwriting check
  119. fi
  120. if test -f Makefile -a "${1}" != "-c" ; then 
  121.   echo shar: Will not over-write existing file \"Makefile\"
  122. else
  123. echo shar: Extracting \"Makefile\" \(864 characters\)
  124. sed "s/^X//" >Makefile <<'END_OF_Makefile'
  125. X# 
  126. X# getline -- a getline to go with fgets
  127. X# 
  128. X# BINDIR is where to put the executable.
  129. X# MANDIR is where the manual pages go, and MANEXT is the extension.
  130. X# for the man pages, e.g., getline.1 or getline.l or getline.m.
  131. X
  132. XBINDIR = /usr/local   -- watch out!
  133. XMANDIR = /usr/man/manl
  134. XMANEXT = l
  135. X
  136. X# These should all just be right if the above ones are.
  137. XDIRNAME = $(BINDIR)/getline
  138. XDIRNAME_M = $(MANDIR)/getline.$(MANEXT)
  139. XLDFLAGS =
  140. XCFLAGS = -g -DTEST
  141. X
  142. Xgetline: getline.c
  143. X    $(CC) $(CFLAGS) $(LDFLAGS) -o getline getline.c
  144. X    @-size getline
  145. X
  146. Xinstall: $(DIRNAME_M)
  147. X
  148. X$(DIRNAME): getline.c
  149. X    $(CC) $(LDFLAGS) -o getline getline.c
  150. X    install -c -m 755 getline $(DIRNAME)
  151. X
  152. X$(DIRNAME_M): getline.1
  153. X    cp getline.1 $(DIRNAME_M)
  154. X    chmod 644 $(DIRNAME_M)
  155. X
  156. X
  157. X
  158. Xlint:
  159. X    lint getline.c
  160. Xtags:
  161. X    ctags -w getline.c
  162. Xgetline.shar:
  163. X    shar getline.c Makefile getline.1 > getline.shar
  164. Xclean:
  165. X    rm -f a.out core *.o getline
  166. END_OF_Makefile
  167. if test 864 -ne `wc -c <Makefile`; then
  168.     echo shar: \"Makefile\" unpacked with wrong size!
  169. fi
  170. # end of overwriting check
  171. fi
  172. if test -f getline.1 -a "${1}" != "-c" ; then 
  173.   echo shar: Will not over-write existing file \"getline.1\"
  174. else
  175. echo shar: Extracting \"getline.1\" \(873 characters\)
  176. sed "s/^X//" >getline.1 <<'END_OF_getline.1'
  177. X.TH getline 1,local
  178. X.SH NAME
  179. Xgetline \- get a line of near-arbitrary length from a stream.
  180. X.SH SYNTAX
  181. X.nf
  182. X#include <stdio.h>
  183. X
  184. Xchar *getline(stream)
  185. XFILE *stream;
  186. X.fi
  187. X
  188. X.SH DESCRIPTION
  189. XThe 
  190. X.B getline 
  191. Xroutine reads up to a newline character from the stream
  192. Xinto an internal cache of arbitrary size.  The last character read
  193. Xis followed by a null character.  The getline routine returns
  194. Xits first argument or NULL on end of file or error.
  195. X
  196. X.SH DIAGNOSTICS
  197. XIf a line longer than available memory is read, the program exits
  198. Xwith a message.  This is expected to be a rare event.
  199. X
  200. X.SH "SEE ALSO"
  201. Xferror(3s), fread(3s), getc(3s), puts(3s), scanf(3s), fgets(3).
  202. X
  203. X.SH BUGS
  204. XStrictly dependant on the behavior of fgets: treats a ^D (eof) in
  205. Xmid-stream from a terminal as does fgets (ie, it disappears silently
  206. Xunder Ultrix/Berzerkley)
  207. X.PP
  208. XWritten by Dave (instakludge) Collier-Brown.
  209. END_OF_getline.1
  210. if test 873 -ne `wc -c <getline.1`; then
  211.     echo shar: \"getline.1\" unpacked with wrong size!
  212. fi
  213. # end of overwriting check
  214. fi
  215. echo shar: End of shell archive.
  216. exit 0
  217. -- 
  218.  David Collier-Brown.  {mnetor yunexus utgpu}!geac!daveb
  219.  Geac Computers Ltd.,  | "His Majesty made you a major 
  220.  350 Steelcase Road,   |  because he believed you would 
  221.  Markham, Ontario.     |  know when not to obey his orders"
  222.